package com.powernode.driver.service.impl;

import com.powernode.common.execption.PowerException;
import com.powernode.common.result.ResultCodeEnum;
import com.powernode.driver.properties.TencentProperties;
import com.powernode.driver.service.CiService;
import com.powernode.driver.service.CosService;
import com.powernode.model.vo.driver.CosUploadVo;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class CosServiceImpl implements CosService {
    @Resource
    private TencentProperties tencentProperties;// 腾讯云配置属性
    @Resource
    private CiService ciService;// 内容审核服务

    /**
     * 获取腾讯云COS客户端实例
     * 使用配置的密钥和区域信息创建COS客户端
     *
     * @return COSClient实例，用于操作腾讯云对象存储服务
     */
    private COSClient getCosClient() {
        // 使用腾讯云密钥创建凭证
        COSCredentials cosCredentials = new BasicCOSCredentials(tencentProperties.getSecretId(), tencentProperties.getSecretKey());
        // 设置存储区域
        Region region = new Region(tencentProperties.getRegion());
        // 配置客户端参数
        ClientConfig clientConfig = new ClientConfig(region);
        // 使用HTTPS协议
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 创建并返回COS客户端实例
        COSClient cosClient = new COSClient(cosCredentials, clientConfig);
        return cosClient;
    }

    /**
     * 上传文件到腾讯云COS
     *
     * @param file 要上传的文件
     * @param path 上传路径前缀
     * @return CosUploadVo 包含上传路径和展示URL的对象
     */
    @Override
    public CosUploadVo upload(MultipartFile file, String path) {
        // 获取COS客户端实例
        COSClient cosClient = getCosClient();

        // 设置文件元数据
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(file.getSize()); // 文件大小
        objectMetadata.setContentType(file.getContentType()); // 文件类型
        objectMetadata.setContentEncoding("utf-8"); // 编码格式

        // 获取文件扩展名并生成唯一文件名
        String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        // 构建上传路径：/driver/路径/UUID文件名.扩展名
        String uploadPath = "/driver/" + path + "/" + UUID.randomUUID().toString().replaceAll("-", "") + fileType;

        try {
            // 创建上传请求 参数：桶名、上传路径、文件输入流、元数据
            PutObjectRequest putObjectRequest = new PutObjectRequest(tencentProperties.getBucketPrivate(), uploadPath, file.getInputStream(), objectMetadata);
            // 设置存储类型为标准存储
            putObjectRequest.setStorageClass(StorageClass.Standard);

            // 执行上传操作
            cosClient.putObject(putObjectRequest);
            // 关闭客户端连接
            cosClient.shutdown();

            // 审核图片
            Boolean isAuditing = ciService.imageAuditing(uploadPath);
            if(!isAuditing) {
                //删除违规图片
                cosClient.deleteObject(tencentProperties.getBucketPrivate(), uploadPath);
                throw new PowerException(ResultCodeEnum.IMAGE_AUDITION_FAIL);
            }

            // 构建返回结果
            CosUploadVo cosUploadVo = new CosUploadVo();
            cosUploadVo.setUrl(uploadPath); // 设置文件路径
            String imageUrl = getImageUrl(path); // 获取图片访问URL
            cosUploadVo.setShowUrl(imageUrl); // 设置展示URL

            return cosUploadVo;
        } catch (IOException e) {
            // 异常处理：将IOException转换为RuntimeException
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取文件的公开访问URL
     *
     * @param path 文件在COS中的路径
     * @return 公开访问URL字符串
     */
    @Override
    public String getImageUrl(String path){
        // 获取COS客户端实例
        COSClient cosClient = getCosClient();
        // 创建预签名URL请求 参数：私有存储桶名、文件路径、HTTP GET方法
        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(tencentProperties.getBucketPrivate(), path, HttpMethodName.GET);
        // 设置URL过期时间为当前时间加20分钟
        Date expiration = new DateTime().plusMinutes(20).toDate();
        generatePresignedUrlRequest.setExpiration(expiration);
        // 生成预签名URL
        URL url = cosClient.generatePresignedUrl(generatePresignedUrlRequest);
        // 关闭客户端连接
        cosClient.shutdown();
        // 输出生成的URL到控制台（调试用）
        System.out.println("image url:" + url);
        // 返回URL字符串
        return url.toString();
    }
}
